package ie.dcu.spca.view;

import ie.dcu.spca.R;
import ie.dcu.spca.data.BasicDataManager;
import ie.dcu.spca.model.Bean;

import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public abstract class DataList extends ListActivity {

    public static final String IS_ADD = "addNewData";

    public DataList() {
        super();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        beforeOnCreateInvoke(savedInstanceState);
        super.onCreate(savedInstanceState);
        afterOnCreateInvoke(savedInstanceState);
    }

    protected void beforeOnCreateInvoke(Bundle savedInstanceState) {
    }

    protected void afterOnCreateInvoke(Bundle savedInstanceState) {
        setContentView(R.layout.list);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Map<String, Object> dataMap = (Map<String, Object>) l
                .getItemAtPosition(position);

        Bundle bundle = new Bundle();
        setBundleOnListItemClick(bundle, dataMap);

        startCRUDDialog(bundle);
    }

    /**
     * Set Bundle for communication between list activity and CRUD dialog
     * activity Default it's setting the ID and IS_ADD=false
     * 
     * @param bundle
     * @param dataMap
     *            DataMap from ItemList
     */
    protected void setBundleOnListItemClick(Bundle bundle,
            Map<String, Object> dataMap) {
        bundle.putInt(BasicDataManager.ID, (Integer) dataMap
                .get(BasicDataManager.ID));
        setBundleBeforeStartCRUDDialogForUpdate(bundle, dataMap);
        bundle.putBoolean(IS_ADD, false);
    }

    protected abstract void setBundleBeforeStartCRUDDialogForUpdate(
            Bundle bundle, Map<String, Object> dataMap);

    /**
     * Start Activity of CRUD Dialog
     * 
     * @param bundle
     */
    protected void startCRUDDialog(Bundle bundle) {
        Intent intent = new Intent();
        intent.setClass(this, getCRUDDialog());
        intent.putExtras(bundle);
        startActivity(intent);
    }

    protected abstract Class getCRUDDialog();

    protected abstract BasicDataManager getBeanDataManager();

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            refreshDataOnWindowHasFocus();
        }
    }

    protected abstract List<Bean> getDataListForRefreshOnWindowHasFocus();

    protected void refreshDataOnWindowHasFocus() {
        List<Bean> beanList = getDataListForRefreshOnWindowHasFocus();

        setListAdapter(getIdNameSimpleAdapter(this, getBeanDataManager()
                .getIdNameMapList(beanList)));
    }

    public static SimpleAdapter getIdNameSimpleAdapter(Activity parent,
            List<Map<String, Object>> data) {
        return new SimpleAdapter(parent, data, R.layout.name_info_view,
                new String[] { BasicDataManager.NAME },
                new int[] { R.id.nameTextView });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.add_data_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.addDataItemButton:
            addNewDataItem();
            break;
        case R.id.cancelOptButton:
            this.finish();
            break;
        default:
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    private void addNewDataItem() {
        Bundle bundle = new Bundle();
        bundle.putBoolean(IS_ADD, true);
        setBundleBeforeStartCRUDDialogForAdd(bundle);
        startCRUDDialog(bundle);
    }

    /**
     * Set Bundle for communication
     * 
     * @param bundle
     */
    protected void setBundleBeforeStartCRUDDialogForAdd(Bundle bundle) {

    }

}
